﻿namespace OboutInc
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Xml;

    internal class CallbackData
    {
        private string _event;
        private Hashtable _values = new Hashtable();

        public CallbackData(Stream inputStream)
        {
            XmlDocument document = new XmlDocument();
            this._values.Clear();
            try
            {
                document.Load(inputStream);
            }
            catch (Exception)
            {
                this._event = "FakeEvent";
                return;
            }
            XmlNodeList elementsByTagName = document.GetElementsByTagName("ob_post");
            if (elementsByTagName.Item(0).Attributes.Item(0).Name != "eventname")
            {
                throw new Exception("Invalid Callback request! No method name found.");
            }
            this._event = elementsByTagName.Item(0).Attributes.Item(0).Value;
            elementsByTagName = document.GetElementsByTagName("param");
            for (int i = 0; i < elementsByTagName.Count; i++)
            {
                string key = elementsByTagName[i].Attributes["name"].Value;
                object innerText = null;
                if (elementsByTagName[i].HasChildNodes)
                {
                    if (elementsByTagName[i].Attributes["isnull"] != null)
                    {
                        innerText = null;
                    }
                    else if (elementsByTagName[i].FirstChild.NodeType == XmlNodeType.CDATA)
                    {
                        innerText = elementsByTagName[i].FirstChild.InnerText;
                    }
                    else
                    {
                        innerText = this.createCollectionFromXML(elementsByTagName[i].FirstChild);
                    }
                }
                try
                {
                    this._values.Add(key, innerText);
                }
                catch
                {
                    throw new Exception("Invalid Callback request! Duplicate parameters found (" + elementsByTagName[i].Attributes[0].Value + ")!");
                }
            }
        }

        private CallbackCollection createCollectionFromXML(XmlNode element)
        {
            CallbackCollection callbacks = new CallbackCollection(false);
            if (element.ChildNodes.Count > 0)
            {
                callbacks = new CallbackCollection(element.FirstChild.Attributes["name"] != null);
                foreach (XmlNode node in element.ChildNodes)
                {
                    object innerText = null;
                    object name = null;
                    if (node.FirstChild != null)
                    {
                        if (callbacks.IsAssociative)
                        {
                            name = node.Attributes["name"].Value;
                        }
                        if (node.FirstChild.NodeType == XmlNodeType.CDATA)
                        {
                            innerText = node.FirstChild.InnerText;
                        }
                        else
                        {
                            innerText = this.createCollectionFromXML(node.FirstChild);
                        }
                    }
                    callbacks.Add(name, innerText);
                }
            }
            return callbacks;
        }

        public string Event
        {
            get
            {
                return this._event;
            }
        }

        public Hashtable Values
        {
            get
            {
                return this._values;
            }
        }
    }
}

